-
Notifications
You must be signed in to change notification settings - Fork 122
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
log: Adjust masternode staking output to fix issue #648 #1006
log: Adjust masternode staking output to fix issue #648 #1006
Conversation
Nice! Thank you @chrizog for your contribution. Will review it shortly for minor tweaks, if any and should be good to go after. |
src/miner.cpp
Outdated
@@ -917,22 +917,22 @@ void ThreadStaker::operator()(std::vector<ThreadStaker::Args> args, CChainParams | |||
} | |||
static std::atomic<uint64_t> time{0}; | |||
if (GetSystemTimeInSeconds() - time > 120) { | |||
LogPrintf("ThreadStaker: unlock wallet to start minting...\n"); | |||
LogPrint(BCLog::STAKING, "ThreadStaker: unlock wallet to start minting...\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we want to do this, as this is a user actionable item. If this log is being displayed, it's to prompt to user to either unlock, or remove gen=1 if the intent is not to stake.
src/miner.cpp
Outdated
time = GetSystemTimeInSeconds(); | ||
} | ||
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | ||
} | ||
} | ||
|
||
LogPrintf("ThreadStaker: started.\n"); | ||
LogPrint(BCLog::STAKING, "ThreadStaker: started.\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a single log message per staker. Better to leave an auditable log point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change it back
src/miner.cpp
Outdated
@@ -793,7 +793,7 @@ namespace pos { | |||
{ | |||
if (shouldIgnoreMint(ctxState.subNode, blockHeight, creationHeight, subNodesBlockTime, chainparams)) | |||
break; | |||
LogPrint(BCLog::STAKING, "MakeStake: kernel found\n"); | |||
LogPrintf("MakeStake: kernel found\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about we leave this to staking log, but instead tweak the other (LogPrint(BCLog::STAKING, "ThreadStaker: (%s) minted a block!\n", operatorName);
) one to always print since that's more informative?
src/miner.cpp
Outdated
@@ -818,7 +818,7 @@ namespace pos { | |||
{ | |||
if (shouldIgnoreMint(ctxState.subNode, blockHeight, creationHeight, subNodesBlockTime, chainparams)) | |||
break; | |||
LogPrint(BCLog::STAKING, "MakeStake: kernel found\n"); | |||
LogPrintf("MakeStake: kernel found\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above.
src/miner.cpp
Outdated
LogPrint(BCLog::STAKING, "ThreadStaker: (%s) terminated due to a staking error!\n", operatorName); | ||
it = args.erase(it); | ||
continue; | ||
} | ||
else if (status == Staker::Status::minted) { | ||
LogPrintf("ThreadStaker: (%s) minted a block!\n", operatorName); | ||
LogPrint(BCLog::STAKING, "ThreadStaker: (%s) minted a block!\n", operatorName); | ||
nMinted[arg.operatorID]++; | ||
} | ||
else if (status == Staker::Status::initWaiting) { | ||
LogPrintf("ThreadStaker: (%s) waiting init...\n", operatorName); | ||
LogPrint(BCLog::STAKING, "ThreadStaker: (%s) waiting init...\n", operatorName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about instead, we keep the first 2 unchanged. However, for the waiting init
throttle the log message so there's only one every few mins for waiting init
if staking log isn't enabled.
src/miner.cpp
Outdated
|
||
while (!args.empty()) { | ||
boost::this_thread::interruption_point(); | ||
|
||
while (fImporting || fReindex) { | ||
boost::this_thread::interruption_point(); | ||
|
||
LogPrintf("ThreadStaker: waiting reindex...\n"); | ||
LogPrint(BCLog::STAKING, "ThreadStaker: waiting reindex...\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better approach here would be use a throttled logger method for staking log, that throttles psuedo actionable info, like waiting reindex
, waiting init
.
src/miner.cpp
Outdated
else if (status == Staker::Status::stakeWaiting) { | ||
LogPrint(BCLog::STAKING, "ThreadStaker: (%s) Staked, but no kernel found yet.\n", operatorName); | ||
} | ||
} | ||
catch (const std::runtime_error &e) { | ||
LogPrintf("ThreadStaker: (%s) runtime error: %s\n", e.what(), operatorName); | ||
LogPrint(BCLog::STAKING, "ThreadStaker: (%s) runtime error: %s\n", e.what(), operatorName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, I believe both of these should be clearly auditable points to verify what happened, either if orphaned txs are used somewhere prematurely or if there was an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will change them back to LogPrintf as before 👍
Thanks for this. I think a better approach here would be the following:
An alternative that can be quick fix in the meantime:
to staking only.
Let me know what you think. |
I totally agree. I would suggest to add a method "LogPrintFiltered(LogFlags, LogFilter, Args..)" to the Logger class. The LogFilter can be a time throttle filter. It would keep the possibility for adding different log filters in the future. I will push an example here, it can be adjusted then. I will put the PR to WIP and come back then. |
I think the same, all error messages like Wallet unlock or Threadstaker terminated must visible everytime in the Log, not only if a explicit parameter is given. That are all messages which not flood the Log and important to monitor the Node. The ability to see in the log without "debug=staking" which threadstaker minted the block and which hash it minted is immensely important for us for monitoring, especially when more than one staker is running on a server or a staker is running on more than one server. |
As proposed the logs that are not disturbing and only one-time logs are activated again (to Logprintf). The logs for "waiting init" and "staked but no kernel found yet" are now time throttled and logged at most every 10 minutes for each staker (could be adjusted to less or more minutes). If debug=staking, then everything is logged immediately without time throttling to have the full information to debug the node. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the changes overall
src/logging.h
Outdated
// Log everything directly if category is enabled.. | ||
if (LogAcceptCategory((category))) { | ||
LogPrintf(args...); | ||
} else { // .. and otherwise time throttle | ||
if (!time_throttled_filter.filter()) { | ||
LogPrintf(args...); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot to mention here, Category should be enabled and not filtered to be shown, the problem is throttle will override disabled category so it should be
if (LogAcceptCategory(category) && !time_throttled_filter.filter()) {
LogPrintf(args...);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is intended and it's not overriding. The idea above proposed was that if the category is enabled it should log everything (no throttle) for detailed monitoring or debugging.
If the category is not enabled, you get the log throttled (e.g. every 10 minutes), so the debug.log is not flooded but still you get some information sometimes (e.g. the "waiting init" in the staker).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But if you don't enable the category it should not throttle at all, so that's why we need category enabled + not filtered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The implementation is intended like that. If the category is enabled you want the full output (= no throttling). If the category is not enabled, it should log throttled (e.g. only every 10 minutes), to still have some information, but don't get a flooded debug.log.
This is what @prasannavl mentioned above:
- Use a time throttled logger method for staking log, that throttles psuedo actionable info, like waiting reindex, waiting init and
unlock wallet.- Pass all those logs to the time throttled log, and for the time throttled log behaviour, if staking log is enabled, always log. And if it's not, throttle these.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @bvbfan and @prasannavl , do you have any updates on this improvement?
If I rebase to master, can we merge it? Or do you have more comments on it?
Thanks!
Thanks so much @chrizog - this is really good work :) - Sorry for the delay - we had to triage things a bit due to the 2.6.x. Couple of final thoughts however: [Edit] Removed irrelevant point that was a misread on my part.
So, if we introduce a filter, the filter needs to be able to take this pattern over. Thinking through the above, I would like you to consider if it's better to simplify it even further than prematurely engineering an abstraction that might never end up getting utilised elsewhere :) I think using the existing pattern in 3, we can just go ahead merge it right away. While it's admittedly not as "nice" as what you've written, I don't realistically see this being used in many other places at the moment, and if we do, we likely need to give more thought to what the global abstraction has to look like (does the filter need to take the args, does these timed objected need to be held on when the category is on, etc). |
Please disregard the previous note. Thinking further, what I wrote above cannot be applied here. Let me come back on what better options we have here. |
Ok, I do think your approach is a really good way to assimilate with the current code cleanly. However, for the larger abstraction, I think we have two options at this point:
Use the last key or the last message to compare and decide inside the filter. |
Fastest option however, is to just use https://github.com/DeFiCh/ain/pull/1006/files#diff-6bf9d2e37d503f2f3381cd3a41c26e0b9670f26c2cd4571e98d2af9e3767c1a1R926-R930 pattern with a Since each staker runs on a different thread, it's already staker scoped. I'm ok with all of the 3 approaches - though a little less of option 2, since that unnecessarily holds on to the last message. |
Hi, I am not sure, if the link from your last comment points to the place you intended. It just points to my files changed in this PR, so I am not sure what you propose as the "fastest option pattern" in your last comment. |
The interface was probably engineering too much abstraction. I simplified it a lot now and used the keyed approach with a thread_local map. |
Hi @chrizog - this is fantastic - thank you so much! Sorry for taking so long to come back to this. Just made some minor tweaks to merging:
|
Thank you @chrizog for helping iterate on this. Much appreciated. It's not as elaborate as it was with filter interfaces as you initially conceived - but it's simpler and well contained. When use-cases expand, that would be a nice time to take the approach you have planted the seed for and generalize it. :) |
What kind of PR is this?:
/kind fix
What this PR does / why we need it:
If the option debug="staking" is used, there is too much output in a longer operation of a masternode. The output is flooded with "ThreadStaker: (833......db786ce) waiting init...".
However, if no debug="staking" is used, there is almost no information in the output about newly minted blocks.
The log levels are adjusted, so that "waiting init" is only visible if debug=staking is activated. Without debug=staking it is not shown, but still some important information about newly minted blocks is logged.
Which issue(s) does this PR fixes?:
Fixes #648
Additional comments?: